package com.ou.csbs.capstone.tools;

import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.render.BasicShapeAttributes;
import gov.nasa.worldwind.render.Material;
import gov.nasa.worldwind.util.measure.LengthMeasurer;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import com.ou.csbs.capstone.models.RenderableModel;
import com.ou.csbs.capstone.models.shapes.Circle;
import com.ou.csbs.capstone.models.shapes.Line;
import com.ou.csbs.capstone.views.menu.StatusBar;
import com.ou.csbs.capstone.views.worldwind.WorldWindCanvas;

/**
 * The Measurement tool. This tool draws black circles with radii, and indicates to the user through the status bar how long the current radius is. On mouse click, the radius line is kept, but a new
 * circle begins to be drawn centered on the mouse click's position. From there, a total distance is calculated as the sum of the previous radii with the current radius segment.
 * Additionally, the current azimuth in NATO angular mils (based on the current radius) is reported to the user.
 *  
 * @author Senior Capstone
 */
public class MeasurementTool extends MouseAdapter{
	private Circle tempCircle;
	private Line tempLine;
	private ArrayList<Position> positions;
	private RenderableModel model;
	private BasicShapeAttributes measurementAttributes;
	private long lastClickTime;
	private LatLon lastClickPosition;
	private double totalDistance;
	private double segmentDistance;


	public MeasurementTool(RenderableModel model){
		this.model = model;
		positions = new ArrayList<Position>();
		this.measurementAttributes = new BasicShapeAttributes();
		this.measurementAttributes.setOutlineWidth(3);
		this.measurementAttributes.setDrawInterior(false);
		this.measurementAttributes.setOutlineMaterial(Material.BLACK);
		lastClickTime = System.currentTimeMillis();
		
		totalDistance = 0;
		segmentDistance = 0;
	}

	@Override
	public void mousePressed(MouseEvent mouseEvent) {
		Position position = WorldWindCanvas.getWorldWindow().getCurrentPosition();
		if(mouseEvent.getButton() == MouseEvent.BUTTON1 && 
				System.currentTimeMillis() - lastClickTime <= 250 && 
				position.getLatitude().getDegrees() == lastClickPosition.getLatitude().getDegrees() &&
				position.getLongitude().getDegrees() == lastClickPosition.getLongitude().getDegrees()){
			if(tempLine != null){
				tempLine.removeShape(model);
				tempLine = null;
				tempCircle.removeShape(model);
				tempCircle = null;
				positions.clear();
			}else{
				positions.clear();
			}

		}else if(mouseEvent.getButton() == MouseEvent.BUTTON1){
			lastClickTime = System.currentTimeMillis();
			lastClickPosition = position;
			if(position != null){
				if(tempLine != null){
					positions.add(position);
					tempLine.addPosition(position);
					tempCircle.setCenter(position);
					tempCircle.updateRadius(position);
				}else{
					positions.add(position);
					//used to hold the next position point
					positions.add(position);
					tempLine = new Line(this.measurementAttributes, this.positions);
					tempLine.drawShape(this.model);
					tempCircle = new Circle(this.measurementAttributes, position, position);
					tempCircle.drawShape(this.model);
				}
			}
		} 
		mouseEvent.consume();
	}
	
	@Override
	public void mouseClicked(MouseEvent mouseEvent){
		mouseEvent.consume();
	}
	@Override
	public void mouseDragged(MouseEvent mouseEvent){
		mouseMoved(mouseEvent);
		mouseEvent.consume();
	}
	
	@Override
	public void mouseMoved(MouseEvent mouseEvent){
		Position position = WorldWindCanvas.getWorldWindow().getCurrentPosition();
		if(position != null && tempLine != null && tempCircle != null){
			//updates the next position point value
			positions.set(positions.size()-1, position);
			tempLine.updatePoint(positions.size()-1, position);
			tempCircle.updateRadius(position);
			
			ArrayList<Position> segment = new ArrayList<Position>();
			segment.add(positions.get(positions.size() - 2));
			segment.add(position);
			LengthMeasurer lm = new LengthMeasurer(segment);
			segmentDistance = lm.getLength(WorldWindCanvas.getWorldWindModel().getGlobe());	
			totalDistance = tempLine.getLength();
			
			double azimuth = LatLon.greatCircleAzimuth(segment.get(0), segment.get(1)).getDegrees();
			if(azimuth < 0){
				azimuth += 360;
			}
			int azimuthMils = (int) (azimuth * 17.777777777778);

			String measurementText = "Total: " + String.format("%.4g%n", totalDistance) + " m, " +
									 "Segment: " + String.format("%.4g%n", segmentDistance) + " m, " +
									 "Azimuth: " + String.format("%04d%n", azimuthMils) + " mil";
			
			StatusBar.setMeasurementText(measurementText);
		}
	}
}
